package keter.model;

import java.util.List;

import keter.framework.model.base.BaseModel;
import keter.security.AnonymousUserAdapter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import com.google.common.collect.Lists;
import com.jfinal.aop.Before;
import com.jfinal.aop.Enhancer;
import com.jfinal.ext.plugin.tablebind.TableBind;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;

/**
 * Descdription: 用户
  [uid] CHAR(32));
 * @author 顾力行-gulx@neusoft.com
 * @version 1.0.0
 */
@TableBind(tableName="org_user")
public class User extends BaseModel<User> {
    /**
     * Logger for this class
     */
    private static final Logger logger = LoggerFactory.getLogger(User.class);
    
    //dao:用于原子操作
    public static final User dao = new User();
    
    //service:用于需要事务处理的方法
    public static User service = Enhancer.enhance(User.class);
    
    /**
     * 为前台返回安全的用户信息
     * @return 
     * @author  gulixing@msn.com
     * @date    2015年12月3日
     */
    public User getSecuredInfo(){
    	return new User()
    	.set("username", this.get("username"))
    	.set("name", this.get("name"));
    }
    
    /**
     * 仅供登录校验使用
     * @param username
     * @return 
     * @author  gulixing@msn.com
     * @date    2015年12月22日
     */
    public User findByUsername(String username){
        User user = findFirst(
            "select u.id, u.name, u.username, u.password from org_user u where u.username=? limit 1", wrap(username));
        if(user!=null){
        	//通用方法
        	this.set("id", user.getID());
        }
        return user;
    }
    
    public List<User> findAll(){
        List<User> users = find("select * from org_user");
        return users;
    }
    
    /**
	 * 所有 sql 与业务逻辑写在 Model 或 Service 中，不要写在 Controller 中，养成好习惯，有利于大型项目的开发与维护
	 */
	public Page<User> findPaged(int pageNumber, int pageSize) {
		return paginate(pageNumber, pageSize, "select *", "from org_user order by id asc");
	}
    
    public List<Role> getRoleList() {
    	//未登录用户(匿名访问)
    	if(this.get("username").equals(AnonymousUserAdapter.ANONYMOUS_USERNAME)){
    		List<Role> list = Lists.newArrayList();
    		list.add(new Role().set("name", AnonymousUserAdapter.ANONYMOUS_ROLE_NAME));
    		return list;
    	}
//    	logger.info("id:{}",this.get("id").toString());
        return Role.dao.findByUserId(this.getID());
    }
    
    public List<Menu> getMenuList() {
//    	logger.info("id:{}",this.get("id").toString());
    	return Menu.dao.findByRoleList(this.getRoleList());
    }
   
    /**
     * <p>Method ：exist
     * <p>Description : 判断当前账户是否已存在
     * @param username
     * @return 
     * @author  gulixing@msn.com
     * @version 1.0.0
     */
    public boolean exist(String username){
        User user = findFirst(
          "select count(1) as cnt from org_user u where u.username=? limit 1", wrap(username));
        //mysql
        //return user.getLong("cnt")>0;
//        logger.info("cnt is integer:{}",user.get("cnt") instanceof Integer);
        return user.getNum("cnt")>0; 
    }
    
    @Override
    public boolean delete() {
    	Db.update("delete from org_user_role where user_id=?", wrap(this.getID()));
    	return super.delete();
    }
    
    /**
     * 判断当前用户是否为超级管理员
     * @return 
     * @author  gulx@neusoft.com
     * @date    2016年3月24日
     */
    public boolean isAdmin(){
    	getRoleList();
    	for (Role role : getRoleList()) {
    		if(role.get("name").equals(Role.ROLE_ADMIN)){
    			return true;
    		}
		}    		
    	return false;
    }
    
    
    /**
     * <p>Method ：saveDefaultRole
     * <p>Description : 保存用户，并添加默认角色
     * @return 
     * @author  gulixing@msn.com
     * @version 1.0.0
     */
    public boolean saveWithDefaultRole(User user) {
        Role role = Role.dao.findDefaultRole();
    	return saveWithRole(user,role.getID()); 
    }
  
    /**
     * <p>Method ：saveRole
     * <p>Description : 保存用户同时赋予特定的角色
     * @param roleId
     * @return 
     * @author  gulixing@msn.com
     * @version 1.0.0
     */
    @Before(Tx.class)
    public boolean saveWithRole(User user, Object roleId) {
        //不允许注册匿名用户
        if(user.get("username").equals(AnonymousUserAdapter.ANONYMOUS_USERNAME)){
            return true; 
        }
        if(user.exist(user.getStr("username"))){
            return false; 
        }
        //密码加密处理
        user.set("password",new BCryptPasswordEncoder().encode(user.getStr("password")));
        //保存用户
    	user.save();
    	//保存用户和角色的对应关系
    	Record userRole = new Record()
    	.set("user_id", user.getID())
    	.set("role_id", roleId);
    	return Db.save("org_user_role", userRole);
    }
    
    @Override
    public void validate() {
        validator()
        .notEmpty("username")
        .notEmpty("name")
        .min("password", 4);
//        ValidateUtil.getInstance()
//        .notEmpty(this,"username")
//        .notEmpty(this,"name")
//        .min(this,"password", 4);
//        ValidateUtil.notEmpty(this.get("username"));
//        ValidateUtil.notEmpty(this.get("name"));
//        ValidateUtil.notEmpty(this.get("password"));
    }
}